package com.shiva.oms.biz;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sf.shiva.oms.common.constant.CommonConstant;
import com.sf.shiva.oms.common.util.BeanCopyUtil;
import com.sf.shiva.oms.common.util.CollectionUtil;
import com.shiva.oms.logview.domain.CustomTemp2Local;

/**
 * 
 * 系统用于记忆存储在本地的临时数据，实现读取和写入文件
 * 
 * <pre>
 * HISTORY
 * ****************************************************************************
 *  ID    DATE            PERSON            REASON
 *  1     2018年4月23日         LA.01367604           Create
 * ****************************************************************************
 * </pre>
 * 
 * @author LA.01367604
 * @version 1.0
 */
public abstract class AbstractCustomTemp<T extends CustomTemp2Local> {

    private static final Logger logger = LoggerFactory.getLogger(AbstractCustomTemp.class);
    
    protected static final String CURRENT_DIR = System.getProperty("user.dir");
    protected static final String FILE_SEP = CommonConstant.FILE_SEP;
    protected static final String FILE_CHARSET = "UTF-8";

    /**
     * 创建一个新文件
     * 
     * @param fileDir
     * @param fileName
     * @return
     * @author LA.01367604-2018年4月23日
     */
    public File createNewFile(String fileDir, String fileName) {
        File file = null;
        try {
            File fileParent = new File(CURRENT_DIR + FILE_SEP + fileDir);
            if (!fileParent.exists()) {
                fileParent.mkdirs();
            }
            file = new File(CURRENT_DIR + FILE_SEP + fileDir + FILE_SEP + fileName);
            file.createNewFile();
        } catch (IOException e) {
            logger.error("cannot create file:{}-{}", CURRENT_DIR + FILE_SEP + fileDir + FILE_SEP + fileName, e);
        }
        return file;
    }
    
    /**
     * 读取文件，返回字符串
     * 
     * @param file
     * @return
     * @author LA.01367604-2018年4月23日
     * @throws Exception
     */
    public String readFile2String(File file) throws Exception {
        byte[] filecontent = new byte[(int) file.length()];
        FileInputStream in = new FileInputStream(file);
        in.read(filecontent);
        in.close();
        String contentStr = new String(filecontent, FILE_CHARSET);
        return contentStr;
    }

    /**
     * 转换字符串成列表信息，用于读取数据
     * 
     * @param str
     * @return
     * @author YC-2018年5月2日
     */
    protected abstract List<T> transStr2List(String str);
    
    public List<T> init(String fileDir, String fileName, File file) {
        List<T> list = null;
        if (!file.exists()) { // 文件不存在则新建
            file = createNewFile(fileDir, fileName);
            list = new ArrayList<>();
        } else {
            try {
                String contentStr = readFile2String(file);
                list = transStr2List(contentStr);
            } catch (Exception e) {
                logger.error("cannot read file:{}-{}", CURRENT_DIR + FILE_SEP + fileDir + FILE_SEP + fileName, e);
            }
        }
        return list;
    }

    public void remove2List(List<T> list, String id) {
        if (CollectionUtil.isEmpty(list)) {
            return;
        }
        list.removeIf(elem -> id.equals(elem.getId()));
    }

    public void update(List<T> list, String id, T newData) {
        if (CollectionUtil.isEmpty(list)) {
            return;
        }
        list.stream().filter(elem -> id.equals(elem.getId())).findFirst().ifPresent(oldData -> {
            BeanCopyUtil.copyProperties(oldData, newData, false, "id");
        });
    }

    public T getData(List<T> list, String id) {
        if (CollectionUtil.isEmpty(list)) {
            return null;
        }
        return list.stream().filter(elem -> id.equals(elem.getId())).findFirst().orElse(null);
    }

    public void writeString2File(File file, String contents) throws Exception {
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(contents.getBytes());
        fos.close();
    }

    /**
     * 转换列表信息成字符串，用于存储
     * 
     * @param list
     * @return
     * @author YC-2018年5月2日
     */
    protected abstract String transList2Str(List<T> list);

    public void saveAll(List<T> list, File file) {
        if (file == null)
            return;
        try {
            String str = transList2Str(list);
            writeString2File(file, str);
        } catch (Exception e) {
            logger.error("cannot write file --{}", e);
        }
    }

}
